/***************************************************************************//**
 * @file
 * @brief Battery controller
 ******************************************************************************/
#include "main_ui.h"
#if 0
extern uint16_t halGetBatteryVoltageMilliV(void);
extern void emberAfPluginBatteryMonitorDataCallback(uint16_t voltageDeciV);
//extern void emberAfPluginBatteryMonitorReadADCEventHandler(void);
extern void carel_EmberAfPluginBatteryMonitorReadADCEventHandler(void);

static const uint16_t batteryTableCR2450[] = {
	2000,2085,2155,2225,2295,2365,2425,2455,2485,2515,2545,			// 0 - 10
	2585,2625,2645,2655,2665,2675,2695,2705,2715,2725,				// 11 - 20
	2745,2755,2765,2775,2780,2785,2790,2795,2800,2805,				// 21 - 30
	2810,2815,2820,2825,2830,2835,2840,2845,2855,2860,				// 31 - 40
	2865,2870,2875,2880,2885,2890,2895,2900,2905,2910,				// 41 - 50
	2913,2916,2919,2921,2923,2925,2927,2928,2929,2931,				// 51 - 60
	2932,2934,2935,2936,2937,2938,2939,2940,2941,2942,				// 61 - 70
	2943,2944,2945,2946,2947,2948,2949,2951,2953,2955,				// 71 - 80
	2957,2959,2961,2963,2965,2967,2969,2971,2973,2975,				// 81 - 90
	2977,2979,2982,2985,2988,2990,2993,2994,2997,3000				// 91 - 100
};

static bool oneshot = 0;

uint8_t retrievalTableTo100(uint16_t voltage){

	uint8_t index;

	assert(sizeof(batteryTableCR2450)/sizeof(uint16_t) == 101);

	uint8_t i;
	for(i = 0, index = 0; i < 101; i++){
		if(voltage < batteryTableCR2450[i]){
			break;
		}
		index = i;
	}

	return index;
}

uint8_t retrievalTableTo254(uint16_t voltage){

	uint8_t index, index_next;
	uint16_t ret = 0;

	assert(sizeof(batteryTableCR2450)/sizeof(uint16_t) == 101);

	if(voltage <= batteryTableCR2450[0]){
		return 0;
	}

	if(voltage >= batteryTableCR2450[100]){
		return 254;
	}

	uint8_t i;
	for(i = 0, index = 0; i < 101; i++){
		if(voltage < batteryTableCR2450[i]){
			break;
		}
		index = i;
	}

	index_next = index>=100?100:(index+1);


	if(index_next == index){
		ret = index_next * 2.54;
	}else{
		ret = 2.54 * (index + (voltage - batteryTableCR2450[index])/
				(batteryTableCR2450[index_next]-batteryTableCR2450[index]));
	}

	ret = ret>254?254:ret;

	return (uint8_t)ret;
}


void batteryCtl_Tick(void){

	static uint8_t seq = 0;
	uint16_t curVol = 0;

//	emberAfPluginBatteryMonitorReadADCEventHandler();
	carel_EmberAfPluginBatteryMonitorReadADCEventHandler();

	curVol = halGetBatteryVoltageMilliV();

	switch(seq){
		case 0:{
			if(curVol <= BATTERYCTL_LOWVOLTAGE_THRESHOLD_LOW){
				// TODO Alarm low voltage.
				// --
				UTILS_PRINT(UPM_BATTERY, "!! Low Voltage %d mV!!\n", curVol);
				seq ++;
				break;
			}
		} break;
		case 1:{
			if(curVol >= BATTERYCTL_LOWVOLTAGE_THRESHOLD_HIGH){
				UTILS_PRINT(UPM_BATTERY, "!! Low Voltage All Clear %d mV!!\n", curVol);
				seq = 0;
				break;
			}
			// TODO Alarm low voltage.
			// --
			UTILS_PRINT(UPM_BATTERY, "!! Still Low Voltage %d mV!!\n", curVol);
		} break;
		default:
			seq = 0;
			break;
	}
}

void batteryCtl_StartupTick(void){

//	emberAfPluginBatteryMonitorReadADCEventHandler();
	carel_EmberAfPluginBatteryMonitorReadADCEventHandler();
}

void emberAfPluginBatteryMonitorDataCallback(uint16_t voltageDeciV){

	uint8_t vol1, vol2;
	uint8_t i;
	uint8_t endpoint;

	if(mu_GetSysMode() != MU_SYSMODE_NORMAL)
	  return;

	oneshot = false;

	// convert from mV to 100 mV, which are the units specified by zigbee spec for
	// the power configuration cluster's voltage attribute.
  	vol1 = ((uint8_t) (voltageDeciV / MILLI_TO_DECI_CONVERSION_FACTOR));

  	// Test
  	vol2 = retrievalTableTo100(voltageDeciV);

	UTILS_PRINT(UPM_BATTERY,
				  "Battery Monitor %d mV => %d%%.\n",
				  voltageDeciV, vol2);

	// Cycle through all endpoints, check to see if the endpoint has a power
	// configuration server, and if so update the voltage attribute
	for (i = 0; i < emberAfEndpointCount(); i++) {
		endpoint = emberAfEndpointFromIndex(i);
		if (emberAfContainsServer(endpoint, ZCL_POWER_CONFIG_CLUSTER_ID)) {
			emberAfWriteServerAttribute(endpoint,
										 ZCL_POWER_CONFIG_CLUSTER_ID,
										 ZCL_BATTERY_VOLTAGE_ATTRIBUTE_ID,
										 &vol1,
										 ZCL_INT8U_ATTRIBUTE_TYPE);
			emberAfWriteServerAttribute(endpoint,
									   ZCL_POWER_CONFIG_CLUSTER_ID,
									   ZCL_BATTERY_PERCENTAGE_REMAINING_ATTRIBUTE_ID,
									   &vol2,
									   ZCL_INT8U_ATTRIBUTE_TYPE);
		}
	}
}
#endif

